package com.app;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import com.app.terminal.TerminalEmulator;
import com.app.ui.LimitedDocument;
import com.app.ui.LogFileReader;
import com.app.ui.PromptStyler;

public class ReaderWindow extends JFrame {
  private JTextArea textArea;
  private JTextField inputField;
  private TerminalEmulator terminalEmulator;
  private PromptStyler promptStyler;
  private LogFileReader logFileReader;
  private ScheduledExecutorService scheduler;
  private boolean isLogPaused = false;

  // 日志文件1相关变量
  private File currentLogFile = null;
  private long currentPosition = 0;
  private long lastModifiedTime = 0;
  private ScheduledFuture<?> logReaderTask;
  private int logReadDelay = 500; // 默认500毫秒读取一次

  // 日志文件2相关变量
  private File secondaryLogFile = null;
  private long secondaryPosition = 0;
  private boolean isShowingSecondaryLog = false;
  private int secondaryLinesPerEnter = 5; // 每次回车显示的行数

  // 用于保存设置的Preferences对象
  private Preferences prefs;

  // CMD窗口的默认颜色
  private static final Color CMD_BG_COLOR = new Color(0, 0, 0); // 纯黑色背景
  private static final Color CMD_TEXT_COLOR = new Color(240, 240, 240); // 近似白色文本
  private static final Font CMD_FONT = new Font("Microsoft YaHei", Font.PLAIN, 14); // 使用微软雅黑字体支持中文

  public ReaderWindow() {
    terminalEmulator = new TerminalEmulator();
    promptStyler = new PromptStyler();
    logFileReader = new LogFileReader();
    scheduler = Executors.newScheduledThreadPool(1);

    // 初始化Preferences来保存设置
    prefs = Preferences.userNodeForPackage(ReaderWindow.class);

    setTitle("C:\\WINDOWS\\system32\\cmd.exe");
    setSize(800, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);

    // 添加自定义标题面板
    JPanel titlePanel = new JPanel(new BorderLayout());
    titlePanel.setBackground(CMD_BG_COLOR);
    JLabel titleLabel = new JLabel("C:\\WINDOWS\\system32\\cmd.exe");
    titleLabel.setForeground(CMD_TEXT_COLOR);
    titleLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
    titleLabel.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 0));
    titlePanel.add(titleLabel, BorderLayout.WEST);

    // 添加关闭按钮
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
    buttonPanel.setBackground(CMD_BG_COLOR); // 与背景相同的颜色

    // 创建一个没有背景的关闭按钮
    JButton closeButton = new JButton("×");
    closeButton.setForeground(CMD_TEXT_COLOR); // 使用白色文本
    closeButton.setBackground(CMD_BG_COLOR); // 与背景相同的颜色
    closeButton.setFocusPainted(false); // 不显示焦点边框
    closeButton.setContentAreaFilled(false); // 不填充内容区域
    closeButton.setBorderPainted(false); // 不绘制边框
    closeButton.setFont(new Font("Arial", Font.BOLD, 14)); // 使用粗体字
    closeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 鼠标悬停时显示手形光标
    closeButton.setMargin(new Insets(0, 8, 0, 8)); // 增加水平边距

    // 添加鼠标事件监听器来实现悬停效果
    closeButton.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        // 鼠标悬停时变成红色背景（模拟CMD关闭按钮）
        closeButton.setBackground(new Color(232, 17, 35));
        closeButton.setContentAreaFilled(true);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        // 鼠标离开时恢复透明
        closeButton.setBackground(CMD_BG_COLOR);
        closeButton.setContentAreaFilled(false);
      }
    });

    closeButton.addActionListener(e -> {
      saveLogFileSettings();
      System.exit(0);
    });

    buttonPanel.add(closeButton);
    titlePanel.add(buttonPanel, BorderLayout.EAST);

    // 将标题面板添加到窗口的北部
    add(titlePanel, BorderLayout.NORTH);

    // 初始设置黑色背景和白色文字，模拟CMD窗口的外观
    textArea = new JTextArea();
    textArea.setEditable(false);
    JScrollPane scrollPane = new JScrollPane(textArea);
    scrollPane.setBorder(BorderFactory.createEmptyBorder()); // 移除滚动面板边框
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); // 永不显示垂直滚动条
    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // 永不显示水平滚动条

    // 启用行包装，使长文本自动换行
    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true); // 按单词换行，而不是在任意位置

    // 设置文本区域的文本缓冲区大小上限，防止内存溢出
    textArea.setDocument(new LimitedDocument(1000000)); // 限制为100万个字符

    // 应用CMD风格的颜色设置
    textArea.setBackground(CMD_BG_COLOR);
    textArea.setForeground(CMD_TEXT_COLOR);
    textArea.setCaretColor(CMD_TEXT_COLOR);
    textArea.setFont(CMD_FONT);
    textArea.setMargin(new Insets(5, 5, 5, 5)); // 添加一些内边距

    // 添加键盘监听以支持空格键暂停/继续滚动
    textArea.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SPACE && currentLogFile != null) {
          toggleLogPause();
          e.consume(); // 防止空格键被添加到文本区域
        } else if (e.getKeyCode() == KeyEvent.VK_ENTER && secondaryLogFile != null) {
          // 当按下回车键且第二个日志文件已经设置时
          showSecondaryLogLines();
          e.consume();
        }
      }
    });

    add(scrollPane, BorderLayout.CENTER);

    inputField = new JTextField();
    inputField.setBackground(CMD_BG_COLOR);
    inputField.setForeground(CMD_TEXT_COLOR);
    inputField.setCaretColor(CMD_TEXT_COLOR);
    inputField.setFont(CMD_FONT);
    inputField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 移除边框并添加内边距

    inputField.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String command = inputField.getText();
        if (command.trim().isEmpty()) {
          if (secondaryLogFile != null) {
            // 如果命令为空且第二个日志文件已设置，相当于按了回车
            showSecondaryLogLines();
          }
          return;
        }

        textArea.append("C:\\> " + command + "\n"); // 使用CMD风格的提示符
        inputField.setText("");

        // 处理特殊命令
        if (command.equalsIgnoreCase("openlog")) {
          openLogFile(1); // 打开第一个日志文件
        } else if (command.equalsIgnoreCase("openlog2")) {
          openLogFile(2); // 打开第二个日志文件
        } else if (command.equalsIgnoreCase("stoplog")) {
          stopLogReading();
        } else if (command.equalsIgnoreCase("pauselog")) {
          toggleLogPause();
        } else {
          // 执行普通命令
          String result = terminalEmulator.executeCommand(command);
          textArea.append(result + "\n");
        }
      }
    });
    add(inputField, BorderLayout.SOUTH);

    // 设置容器的背景颜色
    Container contentPane = getContentPane();
    contentPane.setBackground(CMD_BG_COLOR);

    // 显示初始提示符，确保使用UTF-8编码
    displayWelcomeMessage();

    // 尝试从上次保存的位置恢复日志文件
    tryRestoreLogFiles();

    // 在窗口关闭前保存日志文件的路径
    addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        saveLogFileSettings();
      }
    });

    // 添加自定义的窗口拖动支持
    addCustomWindowDragSupport();

    // 添加右键菜单
    addContextMenu();

    // 添加窗口大小调整支持
    addResizeSupport();
  }

  /**
   * 创建菜单栏
   */
  private void createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("文件");

    JMenuItem openLogItem = new JMenuItem("打开日志文件1");
    openLogItem.addActionListener(e -> openLogFile(1));
    fileMenu.add(openLogItem);

    JMenuItem openLog2Item = new JMenuItem("打开日志文件2");
    openLog2Item.addActionListener(e -> openLogFile(2));
    fileMenu.add(openLog2Item);

    fileMenu.addSeparator();

    JMenuItem exitItem = new JMenuItem("退出");
    exitItem.addActionListener(e -> {
      saveLogFileSettings();
      System.exit(0);
    });
    fileMenu.add(exitItem);

    menuBar.add(fileMenu);
    setJMenuBar(menuBar);
  }

  /**
   * 打开日志文件
   * 
   * @param fileNumber 文件编号(1或2)
   */
  private void openLogFile(int fileNumber) {
    JFileChooser fileChooser = new JFileChooser();
    fileChooser.setDialogTitle("选择日志文件" + fileNumber);

    // 设置文件过滤器，只显示日志文件和所有文件
    fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
      public boolean accept(File f) {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".log") ||
            f.getName().toLowerCase().endsWith(".txt");
      }

      public String getDescription() {
        return "日志文件 (*.log, *.txt)";
      }
    });

    int result = fileChooser.showOpenDialog(this);

    if (result == JFileChooser.APPROVE_OPTION) {
      File selectedFile = fileChooser.getSelectedFile();

      if (fileNumber == 1) {
        // 处理第一个日志文件
        textArea.append("打开日志文件1: " + selectedFile.getPath() + "\n");

        // 检查文件是否存在且可读
        if (!selectedFile.exists()) {
          textArea.append("错误: 文件不存在!\n");
          return;
        }

        if (!selectedFile.canRead()) {
          textArea.append("错误: 无法读取文件，请检查权限!\n");
          return;
        }

        // 停止任何现有的日志阅读任务
        stopLogReading();

        // 设置新的日志文件并开始读取
        currentLogFile = selectedFile;
        currentPosition = 0; // 始终从头开始
        isLogPaused = false;

        // 保存日志文件1的路径
        prefs.put("primaryLogPath", selectedFile.getAbsolutePath());

        // 开始读取日志
        startLogReading();
      } else if (fileNumber == 2) {
        // 处理第二个日志文件
        textArea.append("打开日志文件2: " + selectedFile.getPath() + "\n");

        // 检查文件是否存在且可读
        if (!selectedFile.exists()) {
          textArea.append("错误: 文件不存在!\n");
          return;
        }

        if (!selectedFile.canRead()) {
          textArea.append("错误: 无法读取文件，请检查权限!\n");
          return;
        }

        // 设置第二个日志文件
        secondaryLogFile = selectedFile;
        // 将文件路径保存到preferences
        prefs.put("secondaryLogPath", selectedFile.getAbsolutePath());
        // 如果没有保存的位置，则从头开始
        if (!prefs.getBoolean("hasSecondaryPosition", false)) {
          secondaryPosition = 0;
        }

        textArea.append("日志文件2已设置。按回车键显示" + secondaryLinesPerEnter + "行内容。\n");
      }
    }
  }

  /**
   * 尝试从上次保存的位置恢复日志文件
   */
  private void tryRestoreLogFiles() {
    // 尝试恢复日志文件1
    String primaryLogPath = prefs.get("primaryLogPath", null);
    if (primaryLogPath != null) {
      File file = new File(primaryLogPath);
      if (file.exists() && file.canRead()) {
        currentLogFile = file;
        currentPosition = 0; // 始终从头开始

        textArea.append("恢复日志文件1: " + file.getPath() + "\n");
        textArea.append("从头开始读取...\n");

        // 开始读取日志文件1
        startLogReading();
      }
    }

    // 尝试恢复日志文件2
    tryRestoreSecondaryLog();
  }

  /**
   * 尝试从上次保存的位置恢复第二个日志文件
   */
  private void tryRestoreSecondaryLog() {
    String savedPath = prefs.get("secondaryLogPath", null);
    if (savedPath != null) {
      File file = new File(savedPath);
      if (file.exists() && file.canRead()) {
        secondaryLogFile = file;

        if (prefs.getBoolean("hasSecondaryPosition", false)) {
          secondaryPosition = prefs.getLong("secondaryPosition", 0);
          // 确保位置不超过文件长度
          if (secondaryPosition > file.length()) {
            secondaryPosition = 0;
          }
        } else {
          secondaryPosition = 0;
        }

        textArea.append("恢复日志文件2: " + file.getPath() + "\n");
        textArea.append("从位置 " + secondaryPosition + " 开始读取\n");
        textArea.append("按回车键显示" + secondaryLinesPerEnter + "行内容。\n");
      }
    }
  }

  /**
   * 保存日志文件的设置
   */
  private void saveLogFileSettings() {
    // 保存日志文件1的路径
    if (currentLogFile != null) {
      prefs.put("primaryLogPath", currentLogFile.getAbsolutePath());
      // 注意：我们不保存currentPosition，因为我们希望每次都从头开始读取
    }

    // 保存日志文件2的路径和位置
    saveSecondaryLogPosition();
  }

  /**
   * 保存第二个日志文件的当前位置
   */
  private void saveSecondaryLogPosition() {
    if (secondaryLogFile != null) {
      prefs.put("secondaryLogPath", secondaryLogFile.getAbsolutePath());
      prefs.putLong("secondaryPosition", secondaryPosition);
      prefs.putBoolean("hasSecondaryPosition", true);
      System.out.println("保存日志文件2位置: " + secondaryPosition);
    }
  }

  /**
   * 显示第二个日志文件的几行
   */
  private void showSecondaryLogLines() {
    if (secondaryLogFile == null || !secondaryLogFile.exists()) {
      textArea.append("错误: 日志文件2未设置或不存在\n");
      return;
    }

    // 暂停第一个日志文件的读取
    boolean wasLogPaused = isLogPaused;
    if (!wasLogPaused) {
      isLogPaused = true;
      textArea.append("[日志文件1已暂停 - 显示日志文件2]\n");
    }

    try {
      // 读取第二个日志文件的指定行数
      LogFileReader.FileReadResult result = logFileReader.readLines(secondaryLogFile, secondaryPosition,
          secondaryLinesPerEnter);

      if (!result.hasContent()) {
        textArea.append("日志文件2已读取完毕或没有新内容\n");
        // 如果第一个日志原来没有暂停，则恢复继续
        if (!wasLogPaused) {
          isLogPaused = false;
          textArea.append("[日志文件1继续滚动]\n");
        }
        return;
      }

      List<String> lines = result.getLines();

      textArea.append("----- 日志文件2 开始 -----\n");

      for (String line : lines) {
        textArea.append(line + "\n");
        // 滚动到最新位置
        textArea.setCaretPosition(textArea.getDocument().getLength());

        // 小延迟使得显示更平滑
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        }
      }

      textArea.append("----- 日志文件2 结束 -----\n");

      // 更新已读取的位置
      secondaryPosition = result.getNewPosition();

      // 保存新的位置
      prefs.putLong("secondaryPosition", secondaryPosition);
      prefs.putBoolean("hasSecondaryPosition", true);

      // 如果第一个日志原来没有暂停，则恢复继续
      if (!wasLogPaused) {
        isLogPaused = false;
        textArea.append("[日志文件1继续滚动]\n");
      }

    } catch (IOException e) {
      textArea.append("读取日志文件2出错: " + e.getMessage() + "\n");
      // 如果原来没有暂停，则恢复继续
      if (!wasLogPaused) {
        isLogPaused = false;
      }
    }
  }

  /**
   * 开始读取日志文件
   */
  private void startLogReading() {
    if (currentLogFile == null) {
      return;
    }

    textArea.append("开始读取日志文件，按空格键暂停/继续...\n");

    // 创建一个单独的线程来读取文件内容
    Thread fileReaderThread = new Thread(() -> {
      try {
        // 读取整个文件内容
        textArea.append("正在加载日志内容...\n");

        // 先尝试打印文件信息到控制台，用于调试
        System.out.println("正在读取文件: " + currentLogFile.getAbsolutePath());
        System.out.println("文件大小: " + currentLogFile.length() + " 字节");

        // 先尝试使用Files API直接读取整个文件内容以进行调试
        try {
          String debugContent = new String(Files.readAllBytes(currentLogFile.toPath()), StandardCharsets.UTF_8);
          if (debugContent.isEmpty()) {
            System.out.println("警告：使用Files API读取的文件内容为空");
          } else {
            System.out.println("文件内容前100个字符: " + debugContent.substring(0, Math.min(100, debugContent.length())));
          }
        } catch (Exception e) {
          System.out.println("使用Files API读取文件时出错: " + e.getMessage());
        }

        // 使用LogFileReader读取内容
        String fileContent = logFileReader.readNewContent(currentLogFile, 0);

        if (fileContent.isEmpty()) {
          SwingUtilities.invokeLater(() -> {
            textArea.append("警告：文件内容为空或无法读取。\n");
            textArea.append("请检查文件是否有内容，并确保文件编码兼容。\n");
          });
          return;
        }

        // 将文件内容按行分割
        String[] lines = fileContent.split("\n");

        SwingUtilities.invokeLater(() -> {
          textArea.append("日志文件共 " + lines.length + " 行\n");
        });

        // 逐行显示内容
        for (int i = 0; i < lines.length; i++) {
          final String line = lines[i];

          // 如果暂停了，等待恢复
          while (isLogPaused) {
            try {
              Thread.sleep(100);
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              return;
            }
          }

          // 如果线程被中断，退出
          if (Thread.currentThread().isInterrupted()) {
            return;
          }

          // 在UI线程中更新文本区域
          SwingUtilities.invokeLater(() -> {
            textArea.append(line + "\n");
            // 滚动到最新位置
            textArea.setCaretPosition(textArea.getDocument().getLength());
          });

          // 添加延迟，模拟打印效果
          try {
            Thread.sleep(50); // 每行之间的延迟
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
          }
        }

        // 更新位置
        currentPosition = currentLogFile.length();

        SwingUtilities.invokeLater(() -> {
          textArea.append("日志文件读取完成。正在监视文件变化...\n");
        });

        // 开始监视文件变化
        startFileWatcher();

      } catch (IOException e) {
        SwingUtilities.invokeLater(() -> {
          textArea.append("读取日志文件出错: " + e.getMessage() + "\n");
          e.printStackTrace();
        });
      }
    });

    fileReaderThread.setDaemon(true); // 设置为守护线程
    fileReaderThread.start();
  }

  /**
   * 开始监视文件变化
   */
  private void startFileWatcher() {
    // 停止现有监视任务（如果有）
    if (logReaderTask != null && !logReaderTask.isCancelled()) {
      logReaderTask.cancel(false);
    }

    // 创建新的监视任务
    logReaderTask = scheduler.scheduleAtFixedRate(() -> {
      if (isLogPaused || currentLogFile == null) {
        return; // 如果暂停或文件为空，跳过
      }

      try {
        // 检查文件是否存在
        if (!currentLogFile.exists()) {
          SwingUtilities.invokeLater(() -> {
            textArea.append("文件不存在或已被删除: " + currentLogFile.getPath() + "\n");
          });
          stopLogReading();
          return;
        }

        // 检查文件大小是否变化
        long fileLength = currentLogFile.length();

        if (fileLength > currentPosition) {
          // 读取新增内容
          String newContent = logFileReader.readNewContent(currentLogFile, currentPosition);

          if (!newContent.isEmpty()) {
            // 将新内容按行分割
            String[] lines = newContent.split("\n");

            for (String line : lines) {
              final String lineToShow = line;

              // 在UI线程中更新
              SwingUtilities.invokeLater(() -> {
                textArea.append(lineToShow + "\n");
                // 滚动到最新位置
                textArea.setCaretPosition(textArea.getDocument().getLength());
              });

              // 添加延迟模拟打印效果
              try {
                Thread.sleep(50);
              } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
              }
            }

            // 更新位置
            currentPosition = fileLength;
          }
        } else if (fileLength < currentPosition) {
          // 文件被截断，重新开始
          SwingUtilities.invokeLater(() -> {
            textArea.append("文件被截断，重新开始读取...\n");
          });
          currentPosition = 0;
        }
      } catch (IOException e) {
        SwingUtilities.invokeLater(() -> {
          textArea.append("监视文件出错: " + e.getMessage() + "\n");
        });
        stopLogReading();
      }
    }, 1, 1, TimeUnit.SECONDS); // 每秒检查一次
  }

  /**
   * 停止读取日志文件
   */
  private void stopLogReading() {
    if (logReaderTask != null && !logReaderTask.isCancelled()) {
      logReaderTask.cancel(true);
      textArea.append("停止读取日志文件\n");
    }
  }

  /**
   * 切换日志暂停/继续状态
   */
  private void toggleLogPause() {
    if (currentLogFile == null) {
      return;
    }

    isLogPaused = !isLogPaused;
    if (isLogPaused) {
      textArea.append("[日志已暂停 - 按空格键继续]\n");
    } else {
      textArea.append("[日志继续滚动]\n");

      // 从暂停中恢复时，创建一个线程检查是否有新内容
      Thread resumeThread = new Thread(() -> {
        try {
          // 检查文件是否有新内容
          long fileSize = currentLogFile.length();
          if (fileSize > currentPosition) {
            // 读取新内容
            String newContent = logFileReader.readNewContent(currentLogFile, currentPosition);

            if (!newContent.isEmpty()) {
              // 逐行显示新内容
              String[] lines = newContent.split("\n");
              for (String line : lines) {
                if (!line.trim().isEmpty()) {
                  // 如果在处理过程中又被暂停，则等待
                  while (isLogPaused && !Thread.currentThread().isInterrupted()) {
                    try {
                      Thread.sleep(100);
                    } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                      return;
                    }
                  }

                  // 如果线程被中断，停止处理
                  if (Thread.currentThread().isInterrupted()) {
                    return;
                  }

                  // 在EDT线程上更新UI
                  final String lineToAppend = line;
                  SwingUtilities.invokeLater(() -> {
                    textArea.append(lineToAppend + "\n");
                    // 滚动到最新内容
                    textArea.setCaretPosition(textArea.getDocument().getLength());
                  });

                  // 每行之间添加延迟，模拟打印效果
                  try {
                    Thread.sleep(100); // 100毫秒的延迟
                  } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                  }
                }
              }

              // 更新当前位置
              currentPosition = fileSize;
            }
          }
        } catch (IOException e) {
          SwingUtilities.invokeLater(() -> {
            textArea.append("读取日志文件出错: " + e.getMessage() + "\n");
          });
        }
      });

      resumeThread.start();
    }
  }

  /**
   * 显示欢迎信息
   */
  private void displayWelcomeMessage() {
    try {
      // 以下字符串使用UTF-8编码，避免出现乱码
      String welcomeText = "Microsoft Windows [版本 10.0.19045.3086]\n" +
          "(c) Microsoft Corporation。保留所有权利。\n\n" +
          "日志阅读器命令:\n" +
          "- openlog: 打开日志文件1\n" +
          "- openlog2: 打开第二个日志文件\n" +
          "- pauselog: 暂停/继续日志滚动\n" +
          "- stoplog: 停止读取日志\n\n" +
          "提示: 也可以通过菜单'文件'打开日志文件\n" +
          "      读取日志1时按空格键可暂停/继续滚动\n" +
          "      设置日志2后按回车键可显示" + secondaryLinesPerEnter + "行内容\n\n" +
          "C:\\> ";

      // 确保字符串是UTF-8编码
      byte[] bytes = welcomeText.getBytes("UTF-8");
      String utf8Text = new String(bytes, StandardCharsets.UTF_8);

      textArea.append(utf8Text);
    } catch (UnsupportedEncodingException e) {
      // 如果UTF-8编码不支持，则使用默认编码
      textArea.append("Microsoft Windows [Version 10.0.19045.3086]\n");
      textArea.append("(c) Microsoft Corporation. All rights reserved.\n\n");
      textArea.append("C:\\> ");
    }
  }

  /**
   * 设置CMD风格主题（黑底白字）
   */
  public void setCmdTheme() {
    // 设置主面板背景色
    Container contentPane = getContentPane();
    contentPane.setBackground(CMD_BG_COLOR);

    // 设置文本区域样式
    textArea.setBackground(CMD_BG_COLOR);
    textArea.setForeground(CMD_TEXT_COLOR);
    textArea.setCaretColor(CMD_TEXT_COLOR);
    textArea.setFont(CMD_FONT);

    // 设置输入框样式
    inputField.setBackground(CMD_BG_COLOR);
    inputField.setForeground(CMD_TEXT_COLOR);
    inputField.setCaretColor(CMD_TEXT_COLOR);
    inputField.setFont(CMD_FONT);
    inputField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    // 设置滚动面板样式
    Component[] components = getContentPane().getComponents();
    for (Component component : components) {
      if (component instanceof JScrollPane) {
        JScrollPane scrollPane = (JScrollPane) component;
        scrollPane.getViewport().setBackground(CMD_BG_COLOR);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
      }
    }

    // 更新UI
    SwingUtilities.updateComponentTreeUI(this);
  }

  /**
   * 设置暗色主题
   */
  public void setDarkTheme() {
    setCmdTheme(); // 默认使用CMD风格主题
  }

  /**
   * 设置亮色主题
   */
  public void setLightTheme() {
    // 即使系统是亮色主题，我们也保持CMD的黑底白字风格
    setCmdTheme();
  }

  @Override
  public void dispose() {
    // 关闭窗口时保存日志文件的设置
    saveLogFileSettings();

    // 关闭窗口时停止所有任务
    if (scheduler != null) {
      scheduler.shutdownNow();
    }
    super.dispose();
  }

  /**
   * 添加自定义的窗口拖动支持
   * 只允许通过标题栏拖动窗口
   */
  public void addCustomWindowDragSupport() {
    final Point dragPoint = new Point();

    // 为标题面板添加拖动支持
    Component titlePanel = getContentPane().getComponent(0); // 标题面板位于北部
    if (titlePanel instanceof JPanel) {
      JPanel panel = (JPanel) titlePanel;

      panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
          dragPoint.x = e.getX();
          dragPoint.y = e.getY();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
          dragPoint.x = 0;
          dragPoint.y = 0;
        }
      });

      panel.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
          Point currentLocation = getLocation();
          // 计算新的位置
          int newX = currentLocation.x + e.getX() - dragPoint.x;
          int newY = currentLocation.y + e.getY() - dragPoint.y;

          // 获取屏幕尺寸
          java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();

          // 确保窗口不会完全移出屏幕
          // 至少保留100像素在屏幕内
          newX = Math.max(newX, -getWidth() + 100);
          newX = Math.min(newX, screenSize.width - 100);

          newY = Math.max(newY, 0); // 不允许移到屏幕顶部以上
          newY = Math.min(newY, screenSize.height - 100);

          // 设置新位置
          setLocation(newX, newY);

          // 如果窗口完全看不到了，重置到屏幕中央
          if (newX <= -getWidth() + 50 || newX >= screenSize.width - 50 ||
              newY <= -getHeight() + 50 || newY >= screenSize.height - 50) {
            setLocationRelativeTo(null); // 重置到屏幕中央
          }
        }
      });
    }
  }

  /**
   * 添加窗口大小调整支持
   */
  private void addResizeSupport() {
    ResizeAdapter resizeAdapter = new ResizeAdapter(this);
    addMouseListener(resizeAdapter);
    addMouseMotionListener(resizeAdapter);
  }

  /**
   * 窗口大小调整适配器
   */
  private class ResizeAdapter extends MouseAdapter {
    private static final int RESIZE_BORDER = 5; // 调整大小的边框宽度
    private int cursor;
    private Point startPoint;
    private Dimension startSize;
    private JFrame frame;

    public ResizeAdapter(JFrame frame) {
      this.frame = frame;
    }

    @Override
    public void mousePressed(MouseEvent e) {
      startPoint = e.getPoint();
      startSize = frame.getSize();

      int x = e.getX();
      int y = e.getY();
      int width = frame.getWidth();
      int height = frame.getHeight();

      // 确定光标类型
      if (x >= width - RESIZE_BORDER && y >= height - RESIZE_BORDER) {
        cursor = Cursor.SE_RESIZE_CURSOR; // 右下角
      } else if (x >= width - RESIZE_BORDER) {
        cursor = Cursor.E_RESIZE_CURSOR; // 右边
      } else if (y >= height - RESIZE_BORDER) {
        cursor = Cursor.S_RESIZE_CURSOR; // 下边
      } else {
        cursor = Cursor.DEFAULT_CURSOR;
      }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
      int x = e.getX();
      int y = e.getY();
      int width = frame.getWidth();
      int height = frame.getHeight();

      // 更新光标
      if (x >= width - RESIZE_BORDER && y >= height - RESIZE_BORDER) {
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
      } else if (x >= width - RESIZE_BORDER) {
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
      } else if (y >= height - RESIZE_BORDER) {
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
      } else {
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
      if (cursor != Cursor.DEFAULT_CURSOR) {
        int dx = e.getX() - startPoint.x;
        int dy = e.getY() - startPoint.y;

        // 根据光标类型调整大小
        if (cursor == Cursor.SE_RESIZE_CURSOR) {
          frame.setSize(startSize.width + dx, startSize.height + dy);
        } else if (cursor == Cursor.E_RESIZE_CURSOR) {
          frame.setSize(startSize.width + dx, startSize.height);
        } else if (cursor == Cursor.S_RESIZE_CURSOR) {
          frame.setSize(startSize.width, startSize.height + dy);
        }
      }
    }
  }

  /**
   * 添加右键菜单来提供基本控制
   */
  private void addContextMenu() {
    JPopupMenu contextMenu = new JPopupMenu();

    JMenuItem openLog1Item = new JMenuItem("打开日志文件1");
    openLog1Item.addActionListener(e -> openLogFile(1));
    contextMenu.add(openLog1Item);

    JMenuItem openLog2Item = new JMenuItem("打开日志文件2");
    openLog2Item.addActionListener(e -> openLogFile(2));
    contextMenu.add(openLog2Item);

    contextMenu.addSeparator();

    JMenuItem togglePauseItem = new JMenuItem("暂停/继续");
    togglePauseItem.addActionListener(e -> toggleLogPause());
    contextMenu.add(togglePauseItem);

    JMenuItem stopItem = new JMenuItem("停止日志");
    stopItem.addActionListener(e -> stopLogReading());
    contextMenu.add(stopItem);

    contextMenu.addSeparator();

    JMenuItem exitItem = new JMenuItem("退出");
    exitItem.addActionListener(e -> {
      saveLogFileSettings();
      System.exit(0);
    });
    contextMenu.add(exitItem);

    // 为文本区域添加右键菜单
    textArea.setComponentPopupMenu(contextMenu);
  }

  public static void main(String[] args) {
    // 设置系统属性以确保正确处理中文
    System.setProperty("file.encoding", "UTF-8");

    SwingUtilities.invokeLater(() -> {
      ReaderWindow window = new ReaderWindow();
      window.setVisible(true);
    });
  }
}